package io.zim.common.aspect;

import io.zim.common.annotation.DataFilter;
import io.zim.common.exception.RRException;
import io.zim.common.utils.Constant;
import io.zim.common.utils.ShiroUtils;
import io.zim.modules.sys.entity.SysUserEntity;
import io.zim.modules.sys.service.SysDeptService;
import io.zim.modules.sys.service.SysRoleDeptService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 数据过滤，切面处理类
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2017/9/17 15:02
 */
@Aspect
@Component
public class DataFilterAspect {
  private static final Logger LOG = LoggerFactory.getLogger(DataFilterAspect.class);
  @Autowired
  private SysDeptService sysDeptService;
  @Autowired
  private SysRoleDeptService sysRoleDeptService;

  @Pointcut("@annotation(io.zim.common.annotation.DataFilter)")
  public void dataFilterCut() {
  }

  @Before("dataFilterCut()")
  public void dataFilter(JoinPoint point) throws Throwable {
    Object params = point.getArgs()[0];
    if (params != null && params instanceof Map) {
      SysUserEntity user = ShiroUtils.getUserEntity();

      //如果不是超级管理员，则只能查询本部门及子部门数据
      if (user.getUserId() != Constant.SUPER_ADMIN) {
        Map map = (Map)params;
        map.put("filterSql", getFilterSQL(user, point));
      }

      return ;
    }

    throw new RRException("要实现数据权限接口的参数，只能是Map类型，且不能为NULL");
  }

  /**
   * 获取数据过滤的SQL
   */
  private String getFilterSQL(SysUserEntity user, JoinPoint point){
    MethodSignature signature = (MethodSignature) point.getSignature();
    DataFilter dataFilter = signature.getMethod().getAnnotation(DataFilter.class);

    String userAlias = dataFilter.userAlias();
    String deptAlias = dataFilter.deptAlias();

    StringBuilder filterSql = new StringBuilder();
    if (StringUtils.isNotEmpty(deptAlias) || StringUtils.isNotBlank(userAlias)) {
      filterSql.append("and (");
      if (StringUtils.isNotEmpty(deptAlias)) {
        //获取子部门ID
        String deptIds = getDeptIdList(user.getUserId());
        filterSql.append(deptAlias).append(" in ( ").append(deptIds).append(" ) ");
        if (StringUtils.isNotBlank(userAlias)) {
          if (dataFilter.self()) {
            filterSql.append(" or ");
          } else {
            filterSql.append(" and ");
          }
        }
      }
      //没有本部门数据权限，也能查询本人数据
      if (StringUtils.isNotBlank(userAlias)) {
        filterSql.append(userAlias).append(" = ").append(user.getUserId());
      }
      filterSql.append(" ) ");
    } else {
      return "";
    }
    LOG.info("====================" + filterSql.toString() + "========================");
    return filterSql.toString();
  }
  /**
   * 取出用户权限
   *
   * @param userId 登录用户Id
   * @return 权限
   */
  private String getDeptIdList(Long userId) {
    @SuppressWarnings("unchecked")
    List<Long> deptIdList = sysRoleDeptService.queryDeptIdListByUserId(userId);

    StringBuilder roleStr = new StringBuilder();
    String alias = "";
    if (deptIdList != null && !deptIdList.isEmpty()) {
      for (Long deptId : deptIdList) {
        String subDeptIds = sysDeptService.getSubDeptIdList(deptId);
        roleStr.append(",");
        roleStr.append(subDeptIds);
      }
      alias = roleStr.toString().substring(1, roleStr.length());
    }
    return alias;
  }
}